package com.example.mydemo1.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mydemo1.utils.QueryWrapperHelper;
import com.example.mydemo1.entity.common.PageParams;
import com.example.mydemo1.entity.common.PageResult;
import com.example.mydemo1.entity.common.AppResp;
import com.example.mydemo1.utils.OrikaBeanMapper;
import com.example.mydemo1.utils.BeanUtil;
import com.example.mydemo1.mapper.SysRoleMapper;
import com.example.mydemo1.entity.vo.SysRoleVO;
import com.example.mydemo1.entity.po.SysRole;
import com.example.mydemo1.service.SysRoleService;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import java.lang.reflect.InvocationTargetException;
import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 角色表 业务层接口实现类
 * </p>
 *
 * @createTime: 2023/09/16 14:29:44
 */
@Service("sysRoleServiceImpl4mydemo1")
@Slf4j
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements SysRoleService {

    @Autowired
    private SysRoleMapper sysRoleMapper;

    @Override
    public AppResp<PageResult<SysRoleVO>> page(PageParams<SysRoleVO> pageParams) {
        SysRole sysRole = OrikaBeanMapper.map(pageParams.getEntityParams(), SysRole.class);
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();
        try {
            QueryWrapperHelper.getInstance().convert(sysRole, queryWrapper);
        } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
            log.error("分页查询参数转换错误", e);
        }

        IPage<SysRole> params = new Page<>();
        params.setCurrent(pageParams.getPageNum());
        params.setSize(pageParams.getPageSize());

        IPage<SysRole> pageResultTmp = sysRoleMapper.selectPage(params, queryWrapper);
        List<SysRoleVO> sysRoleVOs = OrikaBeanMapper.mapAsList(pageResultTmp.getRecords(), SysRoleVO.class);

        PageResult<SysRoleVO> pr = new PageResult<>();
        pr.setCurrent(pageResultTmp.getCurrent());
        pr.setPages(pageResultTmp.getPages());
        pr.setSize(pageResultTmp.getSize());
        pr.setTotal(pageResultTmp.getTotal());
        pr.setRecords(sysRoleVOs);
        return AppResp.success(pr);
    }

    @Override
    public AppResp<SysRoleVO> queryById(String sysRoleId) {
        QueryWrapper<SysRole> queryWrapper = new QueryWrapper<>();

        SysRole sysRole = sysRoleMapper.selectById(sysRoleId);
        if (ObjectUtils.isEmpty(sysRole)) {
            return AppResp.error("您查询的记录不存在，操作失败");
        }

        SysRoleVO sysRoleVO = OrikaBeanMapper.map(sysRole, SysRoleVO.class);
        return AppResp.success(sysRoleVO);
    }

    @Override
    public AppResp<Void> add(SysRoleVO sysRoleVO) {
        SysRole sysRole = OrikaBeanMapper.map(sysRoleVO, SysRole.class);
        // TODO 如果插入前需要根据某个属性判断对象是否存在，请修改下面代码：
        /*
        List<SysRole> coreSysRoles = sysRoleMapper.selectList(new QueryWrapper<SysRole>().lambda()
            .eq(SysRole::getAccount, sysRole.getAccount()));
        if (!ObjectUtils.isEmpty(coreSysRoles)) {
            return AppResp.error("已存在[" + sysRole.getAccount() + "]记录，添加失败");
        }
        */
        // TODO 逻辑删除
        //sysRole.setDeleteFlag(false);
        //sysRole.setCreateAt(LocalDateTime.now());
        //sysRole.setCreateBy("admin");
        return sysRole.insert() ? AppResp.success() : AppResp.error("操作失败，请重试");
    }

    @Override
    public AppResp<Void> delById(String sysRoleId) {
        SysRole sysRole = sysRoleMapper.selectById(sysRoleId);
        if (ObjectUtils.isEmpty(sysRole)) {
            return AppResp.error("删除的对象不存在，操作失败");
        }
        // TODO 逻辑删除
        //sysRole.setDeleteFlag(true);
        //sysRole.setUpdateAt(LocalDateTime.now());
        // TODO 需要改为当前登录的人
        //sysRole.setUpdateBy("admin");
        return sysRole.updateById() ? AppResp.success() : AppResp.error("操作失败，请重试");

        // 下面是真实删除的代码，可以根据需要放开
        /*
        int i = sysRoleMapper.deleteById(sysRoleId);
        return i > 0 ? AppResp.success() : AppResp.error("操作失败，没有该记录");
        */
    }

    @Override
    public AppResp<Void> modify(SysRoleVO sysRoleVO) {
        SysRole sysRole = OrikaBeanMapper.map(sysRoleVO, SysRole.class);

        SysRole existSysRole = sysRoleMapper.selectById(sysRole.getId());
        if (ObjectUtils.isEmpty(existSysRole)) {
            return AppResp.error("不存在[" + sysRole.getId() + "]记录，操作失败");
        }

        try {
            // 将新对象sysRole的值覆盖旧对象existSysRole的值
            BeanUtil.merge(sysRole, existSysRole);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            return AppResp.error("操作失败，"+e.getMessage());
        }

        //existSysRole.setUpdateAt(LocalDateTime.now());
        //existSysRole.setUpdateBy("admin");
        return existSysRole.updateById() ? AppResp.success() : AppResp.error("操作失败，请重试");
    }

    @Override
    public AppResp<Void> batchAdd(List<SysRoleVO> sysRoleVos) {
        List<SysRole> sysRoles = OrikaBeanMapper.mapAsList(sysRoleVos, SysRole.class);

        // 分批插入，没批插入200条
        Lists.partition(sysRoles, 200).forEach(subSysRoles -> {
            // 打开批处理
            try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
                SysRoleMapper mapper = session.getMapper(SysRoleMapper.class);
                // ExecutorType.BATCH，单条插入
                //for (SysRole subSysRole : sysRoles) {
                //    mapper.insert(subSysRole);
                //}
                // ExecutorType.BATCH，批量插入，很多时候比上面的方式快很多
                mapper.batchInsert(subSysRoles);
                session.commit();
                session.clearCache();
            }
        });

        return AppResp.success();
    }

    @Override
    public AppResp<Void> batchModify(List<SysRoleVO> sysRoleVos) {
        List<SysRole> sysRoles = OrikaBeanMapper.mapAsList(sysRoleVos, SysRole.class);

        // 分批插入，没批插入200条
        Lists.partition(sysRoles, 200).forEach(subSysRoles -> {
            // 打开批处理
            try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
                SysRoleMapper mapper = session.getMapper(SysRoleMapper.class);
                // ExecutorType.BATCH，单条
                //for (SysRole subSysRole : sysRoles) {
                //    mapper.updateById(subSysRole);
                //}
                // ExecutorType.BATCH，批量，比单条快，需要在url中配置allowMultiQueries=true
                mapper.batchModify(subSysRoles);
                session.commit();
                session.clearCache();
            }
        });

        return AppResp.success();
    }

    /**
     * 这个是物理删除，注意
     */
    @Override
    public AppResp<Void> batchDelete(List<SysRoleVO> sysRoleVos) {
        List<SysRole> sysRoles = OrikaBeanMapper.mapAsList(sysRoleVos, SysRole.class);

        // 分批插入，没批插入200条
        Lists.partition(sysRoles, 200).forEach(subSysRoles -> {
            // 打开批处理
            try (SqlSession session = sqlSessionFactory.openSession(ExecutorType.BATCH)) {
                SysRoleMapper mapper = session.getMapper(SysRoleMapper.class);
                // ExecutorType.BATCH，单条
                //for (SysRole subSysRole : sysRoles) {
                //    mapper.deleteById(subSysRole);
                //}
                // ExecutorType.BATCH，批量
                mapper.batchDelete(subSysRoles);
                session.commit();
                session.clearCache();
            }
        });

        return AppResp.success();
    }
}
